package com.mlnx.data.dao.iml;

import com.mlnx.common.form.PageForm;
import com.mlnx.common.utils.MyLog;
import com.mlnx.data.dao.BpStore;
import com.mlnx.data.entity.BpInfo;
import com.mlnx.data.pojo.form.BpInfoForm;
import com.mlnx.data.pojo.vo.BpInfoVo;
import com.mlnx.device.util.SortUtil;
import com.mlnx.service.base.properties.MutilDeviceProperties;
import org.shan.spring.mongodb.MongodbUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;

import javax.annotation.PostConstruct;
import java.beans.IntrospectionException;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Repository("bpMongoDB")
public class BpMongoDB implements BpStore {

    private MyLog log = MyLog.getLog(BpMongoDB.class);

    @Autowired
    private MutilDeviceProperties mutilDeviceProperties;

    @PostConstruct
    @Override
    public void init() {

        log.info("开始初始化bp mongodb存储");
        try {
            // 设置血压索引
            Map<String, Sort.Direction> map = new HashMap<>();
            map.put("patientId", Sort.Direction.ASC);
            map.put("time", Sort.Direction.ASC);
            MongodbUtils.setIndex(mutilDeviceProperties.getStore().getBpCollectionName(), map, true);
        } catch (Exception e) {
            log.error(e, "设置血压索引失败，失败已经捕捉不影响使用");
        }

        log.info("初始化bp mongodb存储结束");
    }

    @Override
    public void save(BpInfo bpInfo) {
        bpInfo.setModifiedTime(bpInfo.getTime());
        bpInfo.setTemperature("0");
        bpInfo.setBreath(18);
        bpInfo.setUploaded(0);
        MongodbUtils.save(bpInfo, mutilDeviceProperties.getStore().getBpCollectionName());
    }

    @Override
    public List<BpInfo> getBps(Integer patientId, Long startTime, Long endTime) {
        Criteria criteria = Criteria.where("patientId").is(patientId);
        criteria.and("time").gt(startTime).lt(endTime);
        Query query = Query.query(criteria);
        query.with(new Sort(Sort.Direction.DESC, "time"));

        List<BpInfo> bpInfos = MongodbUtils.find(BpInfo.class, query, mutilDeviceProperties.getStore().getBpCollectionName());

        return bpInfos;
    }

    @Override
    public BpInfoVo getPageBps(PageForm pageForm, BpInfoForm bpInfoForm) {
        Criteria criteria =new Criteria();
        if(bpInfoForm!=null){
            if(bpInfoForm.getDeviceId()!=null){
                criteria.and("deviceId").is(bpInfoForm.getDeviceId()) ;
            }
            if(bpInfoForm.getPatientId()!=null){
                criteria.and("patientId").is(bpInfoForm.getPatientId()) ;
            }
            if(bpInfoForm.getStartTime()!=null){
                criteria.and("time").gt(bpInfoForm.getStartTime()).lt(bpInfoForm.getEndTime());
            }

        }

        Query query = Query.query(criteria);
        query.skip((pageForm.getCurrent() - 1) * pageForm.getSize());
        query.limit(Math.toIntExact(pageForm.getSize()));
        if(bpInfoForm!=null){
            if(bpInfoForm.getSorter()!=null && !"{}".equals(bpInfoForm.getSorter())){
                Map<String,String> map=SortUtil.parseSorter(bpInfoForm.getSorter());

                for (String str:map.keySet()){
                    query.with(new Sort(Sort.Direction.valueOf(map.get(str)), str));
                }
            }
        }
        List<BpInfo> bpInfos = MongodbUtils.find(BpInfo.class, query, mutilDeviceProperties.getStore().getBpCollectionName());
        Integer total = Math.toIntExact(MongodbUtils.count(new Query(criteria), mutilDeviceProperties.getStore().getBpCollectionName()));
        BpInfoVo bpInfoVo =new BpInfoVo();
        bpInfoVo.setRecords(bpInfos);
        bpInfoVo.setTotal(total);
        bpInfoVo.setSize(Math.toIntExact(pageForm.getSize()));
        bpInfoVo.setCurrent(Math.toIntExact(pageForm.getCurrent()));
        return bpInfoVo;
    }


    @Override
    public void updateBp(BpInfo bpInfo) {
        Criteria criteria = Criteria.where("patientId").is(bpInfo.getPatientId());
        criteria.and("time").is(bpInfo.getTime());

        try {
            MongodbUtils.updateFirst(bpInfo, criteria, mutilDeviceProperties.getStore().getBpCollectionName());
        } catch (IntrospectionException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void deleteBp(BpInfo bpInfo) {
        Criteria criteria = Criteria.where("patientId").is(bpInfo.getPatientId());
        criteria.and("time").is(bpInfo.getTime());

        Query query = Query.query(criteria);

        MongodbUtils.remove(query, mutilDeviceProperties.getStore().getBpCollectionName());
    }


}
